/**
 * @description 数字
 * @author 赵致喜
 * @date 2020-04-14 15:49:36
 * @version V1.0.0
 */

/**
 * @functionName integer
 * @param {Number} value 被检测参数
 * @return {Number} 返回结果
 * @description 数字取整数，直接舍去小数位
 * @author 赵致喜
 * @date 2020-04-14 17:14:12
 * @version V1.0.0
 */

export const integer = (value = 0) => {
  return parseInt(value)
}

/**
 * @functionName  integerFloor
 * @param {Number} value 被检测参数
 * @return {Number} 返回结果
 * @description 数字取整数，返回小于参数值的最大整数。
 * @author 赵致喜
 * @date 2020-04-14 16:17:17
 * @version V1.0.0
 */

export const integerFloor = (value = 0) => {
  return Math.floor(value)
}

/**
 * @functionName  integerCeil
 * @param {Number} value 被检测参数
 * @return {Number} 返回结果
 * @description 数字取整数，返回大于参数值的最大整数。
 * @author 赵致喜
 * @date 2020-04-14 16:37:25
 * @version V1.0.0
 */

export const integerCeil = (value = 0) => {
  return Math.ceil(value)
}

/**
 * @functionName  integerRound
 * @param {Number} value 被检测参数
 * @return {Number} 返回结果
 * @description 数字取整数，四舍五入。
 * @author 赵致喜
 * @date 2020-04-14 16:38:25
 * @version V1.0.0
 */

export const integerRound = (value = 0) => {
  return Math.round(value)
}

/**
 * @functionName decimalInterception
 * @param {Number} value 被检测参数
 * @param {Number} number 截取位数
 * @return {Number} 返回结果
 * @description 小数位直接截取
 * @author 赵致喜
 * @date 2020-04-14 17:23:38
 * @version V1.0.0
 */

export const decimalInterception = (value = 0, number = 0) => {
  const digit = Math.pow(10, number)
  return Math.floor(value * digit) / digit
}

/**
* @functionName decimalInterceptionCeil
* @param {Number} value 被检测参数
* @param {Number} number 截取位数
* @return {Number} 返回结果
* @description 小数位截取，返回大于参数值的最大小数
* @author 赵致喜
* @date 2020-04-14 16:51:42
* @version V1.0.0
*/
export const decimalInterceptionCeil = (value = 0, number = 0) => {
  const digit = Math.pow(10, number)
  return Math.ceil(value * digit) / digit
}

/**
 * @functionName decimalInterceptionRound
 * @param {Number} value 被检测参数
 * @param {Number} number 截取位数
 * @return {Number} 返回结果
 * @description 小数位截取，四舍五入
 * @author 赵致喜
 * @date 2020-04-14 16:51:42
 * @version V1.0.0
 */
export const decimalInterceptionRound = (value = 0, number = 0) => {
  return parseFloat(value.toFixed(number))
}

/**
* @functionName percentage
* @param {Number} value 被检测参数
* @param {Number} number 截取位数
* @return {String} 返回结果
* @description 小数位截取，输出百分比数据
* @author 赵致喜
* @date 2020-04-14 17:40:42
* @version V1.0.0
*/
export const percentage = (value = 0, number = 0) => {
  const multiplier = Math.pow(10, number + 2)
  const digit = Math.pow(10, number)
  return (Math.round(value * multiplier) / digit + '%')
}

/**
 * @functionName percentageCalc
 * @param {Array<Number|String>} arr 一组数据
 * @param {Number} number 精度：最多保留多少位小数
 * @return {Array<String>} 返回结果
 * @description 百分比精度计算，使结果总和等于100%
 * @author 赵致喜
 * @date 2020-05-11 16:17:51
 * @version V1.0.0
 */

export const percentageCalc = (arr = [], number = 0) => {
  let flag = false
  const arrNumber = arr.map(function(value) {
    console.log(!Number(value))
    if( !Number(value) ){
      console.warn('数组中含有不符合格式要求的数据！')
      flag = true
    }
    return Number(value)
  })
  if(flag) return false
  const sum = arrNumber.reduce((a, b) => a + b, 0),
      // D是换算成百分比前情况下的小数位数
      D = number < 2 ? 2 : number + 2,
      // E1, E2将小数转化成整数，解决因精度导致小数计算错误的问题
      E1 = Math.pow(10, D),
      E2 = Math.pow(10, D + 2)
  const perArr = arr.map((e, i) => ({
      index: i,
      percentage: Math.round((e / sum).toFixed(D) * E1)
  }))
  const all = perArr.reduce((a, b) => a + b.percentage, 0)
  // 比较计算出的百分比总和和实际总和
  if(all > E1) {
    // 根据误差大小排序
    perArr.sort((a, b) => {
      const aCur = a.percentage * Math.pow(10, 2),
        aReal = Number((arrNumber[a.index] / sum).toFixed(D + 2)) * E2,
        bCur = b.percentage * Math.pow(10, 2),
        bReal = Number((arrNumber[b.index] / sum).toFixed(D + 2)) * E2,
        aError = aCur - aReal,
        bError = bCur - bReal
      return  bError - aError < 0 ? -1 : bError - aError > 0 ? 1 : a.index - b.index // 根据误差排序，如果误差一样，索引小的在前面
    })
    let sumError = all - E1, i = 0
    // 百分比总和多的部分，从误差大的百分比依次扣除
    while(sumError) {
      perArr[i].percentage = perArr[i].percentage - 1
      sumError--
      i++
    }
  }
  if(all < E1) {
    // 根据误差大小排序
    perArr.sort((a, b) => {
      const aCur = a.percentage * Math.pow(10, 2),
        aReal = Number((arrNumber[a.index] / sum).toFixed(number + 2)) * E2,
        bCur = b.percentage * Math.pow(10, 2),
        bReal = Number((arrNumber[b.index] / sum).toFixed(number + 2)) * E2,
        aError = aCur - aReal,
        bError = bCur - bReal
      return  aError - bError < 0 ? -1 : aError - bError > 0 ? 1 : a.index - b.index
    })
    let sumError = all - E1, i = 0
    // 百分比总和少的部分，从误差大的百分比依次补上
    while(sumError) {
      perArr[i].percentage = perArr[i].percentage + 1
      sumError++
      i++
    }
  }
  return perArr.sort((a, b) => a.index - b.index).map(e => (e.percentage / Math.pow(10, D - 2)).toFixed(D - 2) + '%')
}
